#include <iostream>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include "Lock.hpp"
#include <mutex>

using namespace std;

#define NAMESIZE 64

// 定义一个线程数据
typedef struct threadData
{
    char name[NAMESIZE];
    pthread_mutex_t *mutexp;
} threadData;

int tickets = 1000;

void *startRoutine(void *args)
{
    // 让每个线程都能拿到锁
    // pthread_mutex_t *mutex_p = static_cast<pthread_mutex_t *>(args);
    threadData *td = static_cast<threadData *>(args);

    while (true)
    {
        // 加锁
        pthread_mutex_lock(td->mutexp); //如果申请不到，阻塞线程
        if (tickets > 0)
        {
            usleep(1001); // 加入在这，线程切换了
            cout << td->name << " get a ticket: " << tickets << endl;
            tickets--;
            // 解锁
            pthread_mutex_unlock(td->mutexp);

            // 抢完票后，还有其他事情做
            usleep(500);
        }
        else
        {
            // 解锁
            pthread_mutex_unlock(td->mutexp);
            break;
        }
    }

    // 也可以在线程内部malloc空间，也可以将对应的结果数据返回
    // malloc() -- result
    return nullptr;
}

int main()
{
    // 全局锁或者静态锁
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    // malloc 底层一定要调用底层申请函数，brk，
    pthread_t t1, t2, t3, t4;

    // std::mutex mutex_;
    // mutex_.lock();
    // mutex_.unlock();

    threadData *td = new threadData();
    strcpy(td->name, "thread 1");
    td->mutexp = &mutex;
    pthread_create(&t1, nullptr, startRoutine, td);

    // pthread_create(&t1, nullptr, startRoutine, (void *)"thread 1");
    // pthread_create(&t2, nullptr, startRoutine, (void *)"thread 2");
    // pthread_create(&t3, nullptr, startRoutine, (void *)"thread 3");
    // pthread_create(&t4, nullptr, startRoutine, (void *)"thread 4");

    // pthread_join(t1, nullptr);
    // pthread_join(t2, nullptr);
    // pthread_join(t3, nullptr);
    // pthread_join(t4, nullptr);

    pthread_join(t1, nullptr);
    delete td;

    return 0;
}
